home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / source / xcode / wrapcode.txt < prev   
Encoding:
Text File  |  1993-11-10  |  26.3 KB  |  883 lines

  1.  
  2. Hi!
  3.  
  4. Here is the wrapped sprite code, as advertised. It is *far* from optimal,
  5. since I had only one wrapped sprite to worry about in the demo it was 
  6. written for. 
  7.  
  8. It will almost certainly need work to assemble, since it has been taken
  9. from a larger game. If you get *really* stuck, I'm happy to answer e-mail.
  10.  
  11. It consits of "GLOBALS.INC", "STRUCTS.INC", "VGA.INC", "SPRITES.ASM"
  12.  
  13. ********* Cut Here for Globals.INC ------------------------------------------
  14. ;----------------------------------------------------------------------------:
  15. ; GLOBALS.INC                                                                 :
  16. ;                                                                             :
  17. ;----------------------------------------------------------------------------:
  18.  
  19. ;----------------------------------------------------------------------------:
  20. ;            DATA SEGMENT                                                     :
  21. ;----------------------------------------------------------------------------:
  22.  
  23.  
  24. SEGMENT Data_Segment DWORD PUBLIC USE32 'DATA'
  25. ENDS    Data_Segment
  26.  
  27. ;----------------------------------------------------------------------------:
  28. ;            CODE SEGMENT                                                     :
  29. ;----------------------------------------------------------------------------:
  30.  
  31.  
  32. SEGMENT Code_Segment DWORD PUBLIC USE16 'CODE'
  33. ENDS    Code_Segment
  34.  
  35. ;----------------------------------------------------------------------------:
  36. ;            VIDEO SEGMENT                                                      :
  37. ;----------------------------------------------------------------------------:
  38.  
  39. SEGMENT Video_Segment AT 0a000h
  40. ENDS    Video_Segment
  41.  
  42.         
  43. ;----------------------------------------------------------------------------:
  44. ; VGA Globals                                                                 :
  45. ;----------------------------------------------------------------------------:
  46.  
  47.     GLOBAL    Test_Card:NEAR,Unchain:NEAR,Set_VGA_Colour:NEAR
  48.     GLOBAL    Enable_VGA_Bit_Plane:NEAR,Copy_Screen_to_VGA:NEAR
  49.  
  50.     
  51. ;----------------------------------------------------------------------------:
  52. ; file globals                                                                 :
  53. ;----------------------------------------------------------------------------:
  54.  
  55.     GLOBAL Get_File:NEAR,File_Data:BYTE:0fff0h,File_Name_List:WORD
  56.  
  57.  
  58. ;----------------------------------------------------------------------------:
  59. ; Fatal error globals                                                         :
  60. ;----------------------------------------------------------------------------:
  61.  
  62.     GLOBAL Fuckup:FAR
  63.  
  64. ;----------------------------------------------------------------------------:
  65. ; Sprite Globals                                                             :
  66. ;----------------------------------------------------------------------------:
  67.  
  68.     GLOBAL    Display_Unclipped_Sprite:NEAR,Erase_Unclipped_Sprite:NEAR
  69.     GLOBAL    Display_Clipped_Sprite:NEAR,Display_Wrapped_Sprite:NEAR
  70.     GLOBAL    Save_Unclipped_Background:NEAR,Display_Unclipped_Block:NEAR
  71.     GLOBAL    Limit_Sprite:NEAR
  72.     GLOBAL    Set_Up_Frame:NEAR,Separate_Sprite_Planes:NEAR
  73.     GLOBAL    Separate_Mask_Planes:NEAR
  74.     GLOBAL    Set_Up_Sprite:NEAR,Reset_Sprite_Data:NEAR
  75.     GLOBAL    Image_Buffer:BYTE:64000
  76.     GLOBAL    Display_Wrapped_Mask:NEAR
  77.     
  78. Sprite_Item_Size = 32
  79. Frame_Item_Size  = 16
  80.     
  81. ;----------------------------------------------------------------------------:
  82. ; VBlank Globals                                                             :
  83. ;----------------------------------------------------------------------------:
  84.  
  85.     GLOBAL    VBlank_Service:FAR
  86.     GLOBAL    Screen_Buffer:BYTE:64000
  87.  
  88. ;----------------------------------------------------------------------------:
  89. ; Scroll Globals                                                             :
  90. ;----------------------------------------------------------------------------:
  91.  
  92.     GLOBAL    Scroll_Left:NEAR,Scroll_Right:NEAR
  93.  
  94.  
  95. ;----------------------------------------------------------------------------:
  96. ; Symbols for frames of animation                                             :
  97. ;----------------------------------------------------------------------------:
  98.  
  99. Maximum_Sprites = 32
  100. Maximum_Frames = 100
  101. Maximum_Files = Maximum_Frames
  102.         
  103. ;----------------------------------------------------------------------------:
  104. ;    Error numbers                                                             :
  105. ;----------------------------------------------------------------------------:
  106.  
  107. File_Fuckup         EQU 0
  108. Image_Space_Fuckup    EQU 1
  109.  
  110. ****** Cut here for "STRUCTS.INC" ---------------------------------------------
  111. ;----------------------------------------------------------------------------:
  112. ; STRUCTS.INC                                                                 :
  113. ;                                                                             :
  114. ;----------------------------------------------------------------------------:
  115.  
  116.  
  117. ;----------------------------------------------------------------------------:
  118. ; States of sprite                                                             :
  119. ;----------------------------------------------------------------------------:
  120.  
  121. Sprite_Flipped_X    EQU 128
  122. Sprite_Flipped_Y    EQU 64
  123. Sprite_Clipped_X    EQU 32
  124. Sprite_Clipped_Y    EQU 16
  125. Sprite_Enabled        EQU 1
  126.  
  127. ;----------------------------------------------------------------------------:
  128. ; An item in the Sprite List                                                 :
  129. ;----------------------------------------------------------------------------:
  130. Sprite_Swap_Size    EQU     11                    ; 11 bytes to swap on switch
  131.  
  132. STRUC    Sprite_Item
  133.  
  134.     Current_X                dw    0                ; position of sprite on 
  135.     Current_Y                dw    0                ; logical screen
  136.     Current_Frame            dw    0                ; frame in animation frame list
  137.     Current_Background        dw    0ffffh            ; pointer to saved background
  138.     Current_Address         dw    0                ; pointer to address in vidram
  139.     Current_Left_Plane        db    0                ; side of sprite    
  140.  
  141.     Padding                 db    0                ; let's keep it word aligned
  142.     
  143.     Previous_X                dw    0                ; host address of top left
  144.     Previous_Y                dw    0                ; corner of sprite
  145.     Previous_Frame            dw    0     
  146.     Previous_Background     dw    0ffffh
  147.     Previous_Address        dw    0            
  148.     Previous_Left_Plane     db    0                ; pointer to plane of left hand
  149.     
  150.     Inertia                 dw    0
  151.     
  152.     X_Velocity                db    0
  153.     Y_Velocity                db    0
  154.     
  155.     Sprite_State            db    0                ; state of sprite (flipped, clipped)
  156.                             dw    0
  157.                             dw    0
  158.  
  159.  
  160. ENDS    Sprite_Item
  161.  
  162.  
  163. GLOBAL    Sprite_List:Sprite_Item:Maximum_Sprites
  164.  
  165.  
  166. ;----------------------------------------------------------------------------:
  167. ; A frame of animation in the animation list                                 :
  168. ;----------------------------------------------------------------------------:
  169.  
  170. STRUC    Frame_Item
  171.  
  172.     Image_Data            dd    ?                    ; address of image of frame
  173.     Image_X_Size        dw    ?                    ; x and y dimensions
  174.     Image_Y_Size        dw    ?
  175.     Image_Mask            dd    ?                    ; address of count mask
  176.     Image_Data_Size     dw    ?                    ; size of all image data
  177.     Image_Plane_Size    dw    ?                    ; size of 1 planes data in bytes
  178.         
  179. ENDS    Frame_Item
  180.  
  181.  
  182. GLOBAL Frame_List:Frame_Item:Maximum_Frames
  183.  
  184. ;----------------------------------------------------------------------------:
  185. ; The header of a .PCX or .PCC file                                          :
  186. ;----------------------------------------------------------------------------:
  187.  
  188. STRUC    PCX_Header
  189.     Id                        db    ?
  190.     Version                 db    ?
  191.     Encoding_Mode            db    ?
  192.     Bits_per_Pixel            db    ?
  193.     X1                        dw    ?
  194.     Y1                        dw    ?
  195.     X2                        dw    ?
  196.     Y2                        dw    ?
  197.     Horizontal_Resolution    dw    ?
  198.     Vertical_Resolution     dw    ?
  199.     Colour_Map                db    48    dup (?)
  200.     Not_Used                db    ?
  201.     Number_Of_Planes        db    ?
  202.     Bits_per_Plane_Line     dw    ?
  203.     Palette_Information     dw    ?
  204.                             dw    ?
  205.                             dw    ?
  206.     Extra                    db    54    dup (?)
  207. ENDS    PCX_Header
  208.  
  209. ;----------------------------------------------------------------------------:
  210. ; A Colour Look up Table, or Palette!                                         :
  211. ;----------------------------------------------------------------------------:
  212.  
  213.  
  214. STRUC    PCX_CLUT
  215.     Colour_Information        db    3 dup (256 dup (?))
  216. ENDS    PCX_CLUT
  217.  
  218.  
  219. ********* Cut here for "VGA.INC"-----------------------------------------------
  220. ;----------------------------------------------------------------------------:
  221. ;                                                                             :
  222. ; INCLUDE File for VGA constants and useful macros                             :
  223. ;----------------------------------------------------------------------------:
  224.  
  225.  
  226. ;----------------------------------------------------------------------------:
  227. ; Colour VGA register equates                                                 :
  228. ;----------------------------------------------------------------------------:
  229.  
  230.  
  231. ; I/O ports for accessing VGA
  232.  
  233. Miscellaneous_Output_Write_Port EQU 03c2h
  234. Miscellaneous_Output_Read_Port    EQU 03cch
  235. Input_Status_0_Port             EQU 03c2h
  236. Input_Status_1_Port             EQU 03dah
  237. Sequencer_Address_Port            EQU 03c4h
  238. Sequencer_Data_Port             EQU 03c5h
  239. CRTC_Address_Port                EQU 03d4h
  240. CRTC_Data_Port                    EQU 03d5h
  241. Graphics_Address_Port            EQU 03ceh
  242. Graphics_Data_Port                EQU 03cfh
  243. Attribute_Address_Write_Port    EQU 03c0h
  244. Attribute_Address_Read_Port     EQU 03c1h   
  245. PEL_Address_Write_Mode_Port     EQU 03c8h
  246. PEL_Address_Read_Mode_Port        EQU 03c7h
  247. PEL_Data_Port                    EQU 03c9h
  248. DAC_State_Port                    EQU 03c7h
  249. PEL_Mask_Port                    EQU 03c6h
  250.  
  251.  
  252. ; Addresses of sequencer registers
  253.  
  254. Reset                    EQU 0
  255. Clocking_Mode            EQU 1
  256. Map_Mask                EQU 2
  257. Character_Map_Select    EQU 3
  258. Memory_Mode             EQU 4
  259.  
  260. ; Addresses of CRTC registers
  261.  
  262. Horizontal_Total            EQU 0
  263. Horizontal_Display_End        EQU 1
  264. Start_Horizontal_Blanking    EQU 2
  265. End_Horizontal_Blanking     EQU 3
  266. Start_Horizontal_Retrace    EQU 4
  267. End_Horizontal_Retrace        EQU 5
  268. Vertical_Total                EQU 6
  269. Overflow                    EQU 7
  270. Preset_Row_Scan             EQU 8
  271. Max_Scan_Line                EQU 9
  272. Cursor_Start                EQU 10
  273. Cursor_End                    EQU 11
  274. Start_Address_High            EQU 12
  275. Start_Address_Low            EQU 13
  276. Cursor_Location_High        EQU 14
  277. Cursor_Location_Low         EQU 15
  278. Vertical_Retrace_Start        EQU 16
  279. Vertical_Retrace_End        EQU 17
  280. Vertical_Display_End        EQU 18
  281. ;Offset                     EQU 19  ; ATCHUNG!! Name Conflict.
  282. Underline_Location            EQU 20
  283. Start_Vertical_Blanking     EQU 21
  284. End_Vertical_Blanking        EQU 22
  285. Mode_Control                EQU 23
  286. Line_Compare                EQU 24
  287.  
  288. ; Addresses of Graphics registers
  289.  
  290. Set_Reset                EQU 0
  291. Enable_Set_Reset        EQU 1
  292. Colour_Compare            EQU 2
  293. Data_Rotate             EQU 3
  294. Read_Map_Select         EQU 4
  295. Mode                    EQU 5
  296. Miscellaneous            EQU 6
  297. Colour_Dont_Care        EQU 7
  298. Bit_Mask                EQU 8
  299.  
  300. ; Addresses of Attribute registers
  301.  
  302. Palette                     EQU 0
  303. Attribute_Mode_Control        EQU 010h
  304. Overscan_Colour             EQU 011h
  305. Colour_Plane_Enable         EQU 012h
  306. Horizontal_Pixel_Panning    EQU 013h
  307. Colour_Select                EQU 014h
  308.  
  309. MACRO    Wait_for_Vertical_Retrace
  310.         LOCAL    VR_Wait
  311.         PUSH    AX
  312.         PUSH    DX
  313. VR_Wait:
  314.         MOV     DX,Input_Status_1_Port            ; hang around for vblank tick
  315.         IN        AL,DX
  316.         TEST    AL,8
  317.         JZ        SHORT VR_Wait
  318.         POP     DX
  319.         POP     AX
  320. ENDM
  321.  
  322. ;----------------------------------------------------------------------------:
  323. ; Screen Resolution                                                          :
  324. ;----------------------------------------------------------------------------:
  325.  
  326. VGA_X_Resolution EQU 320
  327. VGA_Y_Resolution EQU 200
  328.  
  329. ************** Cut here for SPRITES.ASM --------------------------------------
  330. ;----------------------------------------------------------------------------:
  331. ; Sprites.ASM                                                                :
  332. ; (C) John Connors                                                        1993 :
  333. ;----------------------------------------------------------------------------:
  334.  
  335.         IDEAL
  336.         P386N        
  337.  
  338.         INCLUDE "GLOBALS.INC"                
  339.         INCLUDE "STRUCTS.INC"        
  340.         INCLUDE "VGA.INC"
  341.  
  342.         
  343. ;-----------------------------------------------------------------------------:
  344. ;                                MACROS                                          :
  345. ;-----------------------------------------------------------------------------:
  346.  
  347. ;----------------------------------------------------------------------------:
  348. ; With X in BX and y in CX compute video address, into EDI, mask into AL     :
  349. ; CX, BX preserved EDI, AH destroyed.                                         :
  350. ; * This computes the video address on the currently nondisplayed screen     :
  351. ;----------------------------------------------------------------------------:
  352.  
  353. ; Logical_Scan_Start_Address holds the offset of the page to plot
  354. ; the sprite on.. it will be undefined when you assemble.
  355. ; You need to change it to whatever *your* double buffering code 
  356. ; uses.
  357.  
  358. MACRO    Compute_Video_Address
  359.         ADD     BX,[SMALL Left_Hand_Bit_Plane]
  360.         MOV     AX,CX                            ; width of display in bytes
  361.         SHL     AX,4
  362.         MOV     CX,AX
  363.         SHL     AX,2
  364.         ADD     AX,CX                            ; multiplied by y
  365.         MOV     CX,BX                            ; duplicate x for mask
  366.         SHR     BX,2                            ; shift out bits used for mask
  367.         MOV     DI,[SMALL WORD PTR Logical_Scan_Start_Address]
  368.         ADD     DI,AX                            ; add x and y contributions 
  369.         ADD     DI,BX
  370.         MOV     AL,CL                            ; AL is low bits of X
  371.         AND     AX,3                            ; mask is bottom two bits
  372. ENDM    
  373.  
  374. ;----------------------------------------------------------------------------:
  375. ;            DATA SEGMENT                                                     :
  376. ;----------------------------------------------------------------------------:
  377.  
  378.  
  379. SEGMENT Data_Segment DWORD PUBLIC USE32 'DATA'
  380.         INCLUDE "DATA.INC"
  381.     
  382.         ALIGN    4
  383.         
  384. ;----------------------------------------------------------------------------:
  385. ; buffer to hold sprite image data                                             :
  386. ;----------------------------------------------------------------------------: 
  387.  
  388. Bottom_of_Image_Buffer        dd    0
  389.  
  390. ;----------------------------------------------------------------------------:
  391. ; list of sprites                                                             :
  392. ;----------------------------------------------------------------------------:
  393.  
  394.         ALIGN    4
  395.  
  396. Sprite_List             Sprite_Item Maximum_Sprites DUP (<>)
  397. Sprite_Item_Size            = SIZE Sprite_List
  398.  
  399. ;----------------------------------------------------------------------------:
  400. ; list of frames for animation                                                 :
  401. ;----------------------------------------------------------------------------:
  402.  
  403.         ALIGN    4
  404.  
  405. Frame_List                    Frame_Item Maximum_Frames DUP (<>)
  406. Frame_Item_Size             = SIZE Frame_List
  407.  
  408.  
  409. Map_Mask_Lookup             db 01,02,04,08        ; translate plane # into mask
  410.  
  411. ENDS    Data_Segment
  412.  
  413. ;----------------------------------------------------------------------------:
  414. ;        IMAGE SEGMENT (Segment to hold image data for sprite frames          :
  415. ;----------------------------------------------------------------------------:
  416.  
  417. SEGMENT         Image_Segment PARA PUBLIC USE32 'DATA'
  418.  
  419.                 ALIGN    4
  420.  
  421. Image_Buffer    db 64000 dup (?)                ; a lot of bytes!
  422.                 db 64000 dup (?)
  423.  
  424. ENDS            Image_Segment
  425.  
  426. ;----------------------------------------------------------------------------:
  427. ; Transfer image data of sprites current frame to screen                     :
  428. ; Performs X wrapping only                                                     :
  429. ; Sprite colour 0 is treated as transparent                                  :
  430. ; Enter with sprite number to display in EAX                                 :
  431. ;                                                                            :
  432. ; This code is part of a larger game and I have not time to re-write it so   :
  433. ; that it works with normal mode x sprites                                   :
  434. ; EAX is an index into the Sprite list, which holds X Y co-ords of sprites   :
  435. ; and things like that. The sprite list also contains an index into the      :
  436. ; Image list which holds the raw binary data for sprite images               :
  437. ; The Image is read from a .PCX file and laid out plane by plane             :
  438. ;                                                                            :
  439. ; Plane #1 Row #1, Row #2, Row #3...                                         :
  440. ; Plane #2 Row #1, Row #2, Row #3...                                         :
  441. ;                                                                            :
  442. ; The planes of the image are assumed all to be the size of the largest plane:
  443. ; in the image (so if only plane one has an extra pixel, the others will     :
  444. ; be padded out)                                                             :
  445. ;                                                                             :
  446. ; The code is also far from optimal. For a start neither source or           :
  447. ; or destination of the image transfer to VGA ram is word aligned            :
  448. ; .. and they *pay* me for this..sheesh!                                     :
  449. ;----------------------------------------------------------------------------:
  450.  
  451. PROC    Display_Wrapped_Sprite NEAR
  452.         LOCAL    Wrapped_Width:WORD,UnWrapped_Width:WORD
  453.         LOCAL    Wrap_Flag:BYTE,X_Pixel:WORD,Plane_Size:WORD
  454.         LOCAL    Source_Plane:BYTE,Sprite_State:BYTE
  455.         LOCAL    Plane_Number:WORD,Plane_Width:WORD
  456.         LOCAL    Image_Width:WORD,Image_Height:WORD,Destination_Start:WORD
  457.         LOCAL    Source_Start:WORD =Local_Length
  458.  
  459.         ENTER    Local_Length,0
  460.  
  461.         PUSHAD                                    ; save registers
  462.         PUSH    DS
  463.         
  464.         ASSUME    DS:Data_Segment
  465.         
  466.         MOV     DX,Video_Segment
  467.         MOV     ES,DX                            ; ES points to VGA's segment
  468.         ASSUME    ES:Video_Segment
  469.         
  470.         ERRIF    (Sprite_Item_Size NE 20h)        ; form address of sprite in SI
  471.         MOV     SI,AX
  472.         SHL     SI,5
  473.         ADD     SI,OFFSET Sprite_List
  474.                                                 ; get state of sprite
  475.         MOV     AL,[(Sprite_Item PTR SI).Sprite_State]
  476.         MOV     [Sprite_State],AL            
  477.                                                 ; get sprite x y
  478.         MOV     BX,[(Sprite_Item PTR SI).Current_X]
  479.         MOV     CX,[(Sprite_Item PTR SI).Current_Y]
  480.         MOV     [X_Pixel],BX                    ; save for x wrapping
  481.         CMP     BX,VGA_X_Resolution             ; trivially reject (off right)
  482.         JGE     NEAR @@Done_Last_Pixel
  483.         Compute_Video_Address
  484.         MOV     [Destination_Start],DI            ; video address
  485.         MOV     [Plane_Number],AX                ; first screen plane of sprite 
  486.                                                 ; form frame address in DI
  487.         MOV     DI,[(Sprite_Item PTR SI).Current_Frame]
  488.         SHL     DI,4
  489.         ADD     DI,OFFSET Frame_List
  490.         MOV     AX,[(Frame_Item PTR DI).Image_Plane_Size]
  491.         MOV     [Plane_Size],AX             
  492.                                                 ; get sprite dimensions etc.
  493.         MOV     BX,[(Frame_Item PTR DI).Image_X_Size]
  494.         MOV     [Image_Width],BX  
  495.         MOV     AX,BX                            ; get image width in acc
  496.         ADD     AX,[X_Pixel]
  497.         CMP     AX,VGA_X_Resolution
  498.         SETGE    [Wrap_Flag]                     ; do we need to wrap?
  499.         MOV     AX,BX                            ; work out absolute width of
  500.         AND     AX,NOT 3                        ; a source plane (width of
  501.         CMP     AX,BX                            ; widest plane in source)
  502.         JZ        SHORT @@No_Plane_Adjust
  503.         ADD     AX,4
  504. @@No_Plane_Adjust:
  505.         SHR     AX,2  
  506.         MOV     [Plane_Width],AX
  507.         MOV     CX,[(Frame_Item PTR DI).Image_Y_Size]
  508.         MOV     [Image_Height],CX
  509.                                                 ; get address of sprite image
  510.         MOV     ESI,[(Frame_Item PTR DI).Image_Data] 
  511.         MOV     [Source_Start],SI                ; SI is smallest possible offset
  512.  
  513.         SHR     ESI,16     
  514.         MOV     AX,SI                            ; get address to get image from
  515.         MOV     DS,AX                            ; in DS:SI (sauce)
  516.         ASSUME    DS:NOTHING                        ; where?
  517.  
  518.         MOV     CX,4                            ; four planes
  519. @@Next_Plane:
  520.         PUSH    CX
  521.         ; for each plane
  522.          ; set VGA write plane
  523.         MOV     SI,[Plane_Number]
  524.         MOV     AH,[BYTE CS:@@Map_Mask_Lookup+SI] 
  525.         MOV     AL,Map_Mask
  526.         MOV     DX,Sequencer_Address_Port
  527.         OUT     DX,AX
  528.  
  529.          ; work out physical plane width (ie width of plane as actually 
  530.          ; displayed without padding)
  531.  
  532.         MOV     BX,[Image_Width]
  533.         ADD     BX,CX
  534.         DEC     BX                                ; cx is plane count
  535.         SHR     BX,2                            ; bx is now plane width
  536.         MOV     [UnWrapped_Width],BX            ; assume no wrapping
  537.         MOV     AL,[Wrap_Flag]
  538.         OR        AL,AL                           ; check for wrapping?
  539.         JZ        SHORT @@Wrapping_Done                
  540. @@X_Wrap:       
  541.         MOV     AX,[UnWrapped_Width]            ; yes, we have to adjust
  542.         MOV     BX,VGA_X_Resolution-1           ; sprite width
  543.         SUB     BX,[X_Pixel]
  544.         SHR     BX,2    
  545.         INC     BX
  546.         MOV     [UnWrapped_Width],BX              ; this is the new width
  547.         SUB     AX,BX
  548.         MOV     [Wrapped_Width],AX                ; this is the width of 
  549.                                                 ; the bit on the other side
  550.                                                 ; of the screen
  551. @@Wrapping_Done:        
  552.         MOV     CX,[Image_Height]
  553.         MOVZX    ESI,[Source_Start]
  554. @@No_Source_Adjust:
  555.         MOV     DI,[Destination_Start]
  556.         MOV     DX,320/4                        ; screen row length
  557. @@Next_Row:     
  558.          ; for each row
  559.         PUSH    CX
  560.         PUSH    DI
  561.         PUSH    SI
  562.         MOV     BX,2
  563.         
  564.         MOV     CX,[UnWrapped_Width]
  565.         SHR     CX,1
  566.         JZ        SHORT @@Words_Done
  567.  
  568.         ALIGN    4                                ; optimise loop jump
  569. @@Next_Word:
  570.         LODSW
  571.         OR        AX,AX
  572.         JZ        SHORT @@Transparent_Word        ; most pixels in my
  573.                                                 ; sprites are transparent
  574.                                                 ; so I check for this first
  575.         OR        AL,AL
  576.         JZ        SHORT @@Transparent0
  577.         MOV     [ES:DI],AL
  578. @@Transparent0:
  579.         OR        AH,AH
  580.         JZ        SHORT @@Transparent1
  581.         MOV     [ES:DI+1],AH
  582. @@Transparent1:
  583. @@Transparent_Word:
  584.         ADD     DI,BX
  585.         LOOP    SHORT @@Next_Word
  586. @@Words_Done:
  587.         MOV     CX,[UnWrapped_Width]
  588.         RCR     CX,1
  589.         JNC     SHORT @@Do_Wrapped_Side
  590.          ; copy <physical plane width bytes>
  591.         LODSB
  592.         OR        AL,AL
  593.         JZ        SHORT @@Transparent
  594.         MOV     [ES:DI],AL
  595. @@Transparent:
  596.         INC     DI
  597. @@Do_Wrapped_Side:        
  598.         MOV     AL,[Wrap_Flag]            ; any wrapping ?
  599.         OR        AL,AL
  600.         JZ        SHORT @@Finished_Row   ; no - forget it
  601.         SUB     DI,DX
  602.  
  603. ;
  604. ; Blit the part of the sprite that has been wrapped (if neccessary)
  605. ;
  606.         MOV     CX,[Wrapped_Width]
  607.         SHR     CX,1
  608.         JZ        SHORT @@WWords_Done
  609.  
  610.         ALIGN    4
  611. @@WNext_Word:
  612.         LODSW
  613.         OR        AX,AX
  614.         JZ        SHORT @@WTransparent_Word
  615.         OR        AL,AL
  616.         JZ        SHORT @@WTransparent0
  617.         MOV     [ES:DI],AL
  618. @@WTransparent0:
  619.         OR        AH,AH
  620.         JZ        SHORT @@WTransparent1
  621.         MOV     [ES:DI+1],AH
  622. @@WTransparent1:
  623. @@WTransparent_Word:
  624.         ADD     DI,BX
  625.         LOOP    SHORT @@WNext_Word
  626. @@WWords_Done:
  627.         MOV     CX,[Wrapped_Width]
  628.         RCR     CX,1
  629.         JNC     SHORT @@Finished_Row
  630.          ; copy <wrapped length width bytes>
  631.         LODSB
  632.         OR        AL,AL
  633.         JZ        SHORT @@WTransparent
  634.         MOV     [ES:DI],AL
  635. @@WTransparent:
  636.  
  637. @@Finished_Row:
  638.          ; next row
  639.          ; bump sauce
  640.         POP     SI
  641.         ADD     SI,[Plane_Width]
  642.          ; bump destination
  643.         POP     DI
  644.         ADD     DI,DX
  645.         POP     CX
  646.         LOOP    @@Next_Row
  647. @@Plane_Clipped_Out:
  648.         ; next plane
  649.         ; bump sauce
  650.         MOV     AX,[Plane_Size]
  651.         ADD     [Source_Start],AX
  652.         ; reset destination
  653.         ; bump    plane
  654.         INC     [Plane_Number]                   ; bump onto next physical
  655.         AND     [Plane_Number],3                ; plane
  656.         JNZ     SHORT @@No_Physical_Plane_Adjust
  657.         INC     [Destination_Start]
  658. @@No_Physical_Plane_Adjust:
  659.         POP     CX                                ; get plane count
  660.         MOV     AX,[X_Pixel]                    ; X pixel
  661.         INC     AX
  662.         CMP     AX,VGA_X_Resolution
  663.         JL        SHORT @@No_Wrap_Check            ; finish if off screen
  664.         XOR     BL,BL
  665.         MOV     [Wrap_Flag],BL                    ; turn off wrapping
  666.         MOV     BX,320/4                        ; if whole plane is wrapped
  667.         SUB     [Destination_Start],BX          ; and bump up a screen line
  668.         XOR     AX,AX
  669. @@No_Wrap_Check:
  670.         MOV     [X_Pixel],AX
  671.         DEC     CX
  672.         JNZ     NEAR @@Next_Plane
  673. @@Done_Last_Pixel:
  674.  
  675.         POP     DS                                ; restore registers
  676.         POPAD
  677.         
  678.         LEAVE
  679.         
  680.         RET     
  681. @@Map_Mask_Lookup:
  682.         db    01
  683.         db    02
  684.         db    04
  685.         db    08
  686. ENDP    Display_Wrapped_Sprite
  687.  
  688.  
  689. ;----------------------------------------------------------------------------:
  690. ; Transfer image data of sprites current frame to screen                     :
  691. ; Sprite colour 0 is *not* treated as transparent                             :
  692. ; Enter with EAX           as sprite number to display                         :
  693. ;----------------------------------------------------------------------------:
  694.  
  695. ; you don't actually need this, but ....
  696. ; i thought t'would be handy!
  697.  
  698. PROC    Display_Unclipped_Block NEAR
  699.         LOCAL    Plane_Size:WORD,Plane_Number:WORD,Physical_Plane_Width:WORD
  700.         LOCAL    Plane_Width:WORD,Bytes_In_Plane:WORD,Image_Width:WORD
  701.         LOCAL    Image_Height:WORD,Destination_Start:WORD
  702.         LOCAL    Source_Start:WORD =Local_Length
  703.  
  704.         ENTER    Local_Length,0
  705.  
  706.         PUSHAD                                    ; save registers
  707.         PUSH    DS
  708.         
  709.         ASSUME    DS:Data_Segment
  710.         
  711.         MOV     DX,Video_Segment
  712.         MOV     ES,DX                            ; ES points to VGA's segment
  713.         ASSUME    ES:Video_Segment
  714.  
  715.         ERRIF    (Sprite_Item_Size NE 20h)        ; form address of sprite in SI
  716.         MOV     SI,AX
  717.         SHL     SI,5
  718.         ADD     SI,OFFSET Sprite_List
  719.                                                 ; form video destination addr 
  720.         MOV     BX,[(Sprite_Item PTR SI).Current_X]
  721.         MOV     CX,[(Sprite_Item PTR SI).Current_Y]
  722.         Compute_Video_Address
  723.         MOV     [Destination_Start],DI
  724.                                                 ; get first plane of sprite 
  725.         MOV     [Plane_Number],AX
  726.                                                 ; form frame address in DI
  727.         MOV     DI,[(Sprite_Item PTR SI).Current_Frame]
  728.         SHL     DI,4
  729.         ADD     DI,OFFSET Frame_List
  730.         MOV     AX,[(Frame_Item PTR DI).Image_Plane_Size]
  731.         MOV     [Plane_Size],AX     
  732.                                                 ; get sprite dimensions etc.
  733.         MOV     BX,[(Frame_Item PTR DI).Image_X_Size]
  734.         MOV     [Image_Width],BX   
  735.         MOV     AX,BX
  736.         AND     AX,NOT 3
  737.         CMP     AX,BX
  738.         JZ        SHORT @@No_Plane_Adjust
  739.         ADD     AX,4
  740. @@No_Plane_Adjust:
  741.         SHR     AX,2  
  742.         MOV     [Plane_Width],AX
  743.         MOV     CX,[(Frame_Item PTR DI).Image_Y_Size]
  744.         MOV     [Image_Height],CX
  745.                                                 ; get address of sprite image
  746.         MOV     ESI,[(Frame_Item PTR DI).Image_Data] 
  747.         MOV     [Source_Start],SI                ; SI is smallest possible offset
  748.  
  749.         SHR     ESI,16                            ; high word of ESI is segment
  750.         MOV     AX,SI
  751.         MOV     DS,AX                            ; in DS:SI (sauce)
  752.         ASSUME    DS:NOTHING                        ; where?
  753.         MOV     CX,4                            ; four planes
  754. @@Next_Plane:
  755.         PUSH    CX
  756.         ; for each plane
  757.          ; set write plane
  758.         MOV     SI,[Plane_Number]                ; convert plane # to mask
  759.         MOV     AH,[BYTE CS:@@Map_Mask_Lookup+SI] 
  760.         MOV     AL,Map_Mask
  761.         MOV     DX,Sequencer_Address_Port
  762.         OUT     DX,AX                            ; send to hardware
  763.          ; work out physical plane width
  764.         MOV     BX,[Image_Width]
  765.         ADD     BX,CX                            ; cx is plane count
  766.         DEC     BX
  767.         SHR     BX,2                            ; bx is now plane width
  768.         MOV     [Physical_Plane_Width],BX
  769.         MOVZX    ECX,[Image_Height]
  770.         MOV     SI,[Source_Start]
  771.         MOV     DI,[Destination_Start]
  772.         MOV     DX,320/4                        ; screen row length
  773.         SUB     DX,[Physical_Plane_Width]
  774.         
  775.         ALIGN    4
  776. @@Next_Row:     
  777.          ; for each row
  778.         PUSH    BX        
  779.         PUSH    CX
  780.         PUSH    SI
  781.  
  782.         
  783.         MOV     CX,BX                            ; bx == [Physical_Plane_Width]
  784.          ; copy <physical plane width bytes>
  785.          
  786.         TEST    DI,3
  787.         JZ        SHORT @@Dword_Aligned
  788.         MOV     CX,DI
  789.         AND     CX,3
  790.         SUB     BX,CX        
  791. @@Align_Data:
  792.         LODSB
  793.         OR        AL,AL
  794.         JZ        SHORT @@Lead_Transparent
  795.         MOV     [ES:DI],AL
  796. @@Lead_Transparent:
  797.         INC     DI
  798.         LOOP    SHORT @@Align_Data
  799.  
  800. @@Dword_Aligned:
  801.  
  802.         MOVZX    ECX,BX
  803.         SHR     ECX,2
  804.         REP     MOVSD
  805.         MOV     CX,BX                            ; bx == [Physical_Plane_Width]
  806.         AND     CX,3
  807.         REP     MOVSB                        
  808.          ; next row
  809.          ; bump sauce
  810.         POP     SI
  811.         ADD     SI,[Plane_Width]
  812.          ; bump destination
  813.         ADD     DI,DX                            ; DX == 320/4
  814.         POP     CX
  815.         POP     BX
  816.         LOOP    SHORT @@Next_Row
  817.         ; next plane
  818.         ; bump sauce
  819.         MOV     AX,[Plane_Size]
  820.         ADD     [Source_Start],AX
  821.         ; reset destination
  822.         ; bump    plane
  823.         INC     [Plane_Number]
  824.         AND     [Plane_Number],3
  825.         JNZ     SHORT @@No_Physical_Plane_Adjust
  826.         INC     [Destination_Start]
  827. @@No_Physical_Plane_Adjust:
  828.         POP     CX
  829.         LOOP    SHORT @@Next_Plane
  830.                 
  831.         POP     DS                                ; restore registers
  832.         POPAD
  833.         
  834.         LEAVE
  835.  
  836.         RET     
  837. @@Map_Mask_Lookup:
  838.         db    01
  839.         db    02
  840.         db    04
  841.         db    08
  842. ENDP    Display_Unclipped_Block
  843.  
  844. ;----------------------------------------------------------------------------:
  845. ; Limit Sprite : Limits sprite to screen borders                             :
  846. ; Enter with EAX as sprite number                                             :
  847. ;----------------------------------------------------------------------------:
  848.  
  849. PROC    Limit_Sprite NEAR
  850.         PUSHA
  851.         ASSUME    DS:Data_Segment
  852.         SHL     AX,5                            ; from sprite address
  853.         MOV     SI,AX
  854.         ADD     SI,OFFSET Sprite_List
  855.         MOV     DI,[(Sprite_Item PTR SI).Current_Frame]
  856.         SHL     DI,4                            ; form frame address
  857.         ADD     DI,OFFSET Frame_List
  858.                                                 ; from right bottom sprite 
  859.                                                 ; co-ordinate
  860.         MOV     BX,[(Frame_Item PTR DI).Image_X_Size]      
  861.         MOV     CX,[(Frame_Item PTR DI).Image_Y_Size]
  862.         ADD     BX,[(Sprite_Item PTR SI).Current_X]
  863.         ADD     CX,[(Sprite_Item PTR SI).Current_Y]
  864.         CMP     BX,VGA_X_Resolution
  865.         JBE     SHORT @@No_X_Clip
  866.         MOV     BX,VGA_X_Resolution         ; form clipped x 
  867.         SUB     BX,[(Frame_Item PTR DI).Image_X_Size]
  868.         MOV     [(Sprite_Item PTR SI).Current_X],BX
  869. @@No_X_Clip:
  870.         CMP     CX,VGA_Y_Resolution     
  871.         JBE     SHORT @@No_Y_Clip
  872.         MOV     CX,VGA_Y_Resolution         ; form clipped y
  873.         SUB     CX,[(Frame_Item PTR DI).Image_Y_Size]
  874.         MOV     [(Sprite_Item PTR SI).Current_Y],CX
  875. @@No_Y_Clip:
  876.         POPA
  877.         RET
  878. ENDP    Limit_Sprite
  879.  
  880. ENDS    Code_Segment
  881.  
  882.  
  883.     END